
module sn76489_tone(
  input  wire        clock_i,
  input  wire        clk_en_i,
  input  wire        res_n_i,
  input  wire        we_i,
  input  wire [7:0]  d_i,
  input  wire        r2_i,
  output reg         ff_o,
  output wire [7:0]  tone_o
);

//Tone register
reg [9:0] f_q;
always @(posedge clock_i or negedge res_n_i)begin
    if(!res_n_i)
        f_q <= #1 10'b0;
    else if(!clk_en_i)
        f_q <= #1 f_q;
    else if(we_i && !r2_i)
        if(!d_i[7])
            f_q <= #1 {d_i[5:0], f_q[3:0]};
        else
            f_q <= #1 {f_q[9:4], d_i[3:0]};
end

//volume register
reg [3:0] a_q;
always @(posedge clock_i or negedge res_n_i)begin
    if(!res_n_i)
        a_q <= #1 4'hf;
    else if(!clk_en_i)
        a_q <= #1 a_q;
    else if(we_i && r2_i)
        a_q <= #1 d_i[3:0];
end

//freq generation
reg [9:0] freq_cnt_q;
always @(posedge clock_i or negedge res_n_i)begin
    if(!res_n_i)
        freq_cnt_q <= #1 10'b0;
    else if(!clk_en_i)
        freq_cnt_q <= #1 freq_cnt_q;
    else if(freq_cnt_q == 10'b0)
        freq_cnt_q <= #1 f_q;
    else
        freq_cnt_q <= #1 freq_cnt_q - 1'b1;
end

reg freq_ff_q;
always @(posedge clock_i or negedge res_n_i)begin
    if(!res_n_i)
        freq_ff_q <= #1 1'b0;
    else if(!clk_en_i)
        freq_ff_q <= #1 freq_ff_q;
    else if(f_q == 10'b0)
        freq_ff_q <= #1 1'b1;
    else if(freq_cnt_q==10'b0)
        freq_ff_q <= ~freq_ff_q;
end

wire [1:0] freq_s = freq_ff_q ? 2'b01 : 2'b11;

sn76489_attenuator U_sn76489_attenuator(
    .attenuation_i  ( a_q    ) ,
    .factor_i       ( freq_s ) ,
    .product_o      ( tone_o )
);

endmodule

